feat: implement multi-skill architecture for AI coding assistants and add AI Resources documentation#443
feat: implement multi-skill architecture for AI coding assistants and add AI Resources documentation#443yixyxiu wants to merge 9 commits into
Conversation
Add a set of Agent Skills (agentskills.io spec) that teach AI tools how to build on CKB with the CCC SDK: - Hub skill: ckb-ccc-fundamentals (Cell model, package selection, address/amount handling, hallucination guard) - Spoke skills: ckb-ccc-signer-setup, ckb-ccc-transactions, ckb-ccc-udt, ckb-ccc-spore, ckb-ccc-playground, ckb-ccc-examples-finder Installable via `npx skills add ckb-devrel/ccc`. Includes a maintenance README documenting version bump discipline and update workflow.
- Remove packages/docs/public/skill.md (475 lines) - the old monolithic skill file - Add AI Resources section metadata (meta.json and meta.zh.json) - Update llms.txt route to reference skill.md as "Agent skills index" and add AI Resources link - Refactor playground guide Example 2 from UDT token issuance to Spore creation (both EN and ZH) - Update verify-llm.mjs script references This is part of the multi-skill architecture migration where the single skill.md is replaced by a hub skill (ckb-ccc-fundamentals) plus spoke skills for each task domain.
- Add /skill.md route (app/skill.md/route.ts) with hub/spoke skill table, dependencies, and npx skills CLI installation - Add AI Resources section with 4 pages (EN and ZH): - index: overview and navigation cards - set-up-ai-tools: npx skills add installation, keep-skills-up-to-date section - prompting-best-practices: skill-native vs web chat prompt templates, 7 task categories - verify-and-troubleshoot: canary questions, npx skills check/update troubleshooting - Update docs meta.json/meta.zh.json to include AI Resources section - Update introduction.zh.mdx to reference new skill.md endpoint This completes the multi-skill architecture migration by providing the new modular skill structure and comprehensive AI tooling documentation.
- Add XudtSusIssuer class that encapsulates the 3-step SUS flow: 1. Create seal cell (reserved until mint) 2. Create owner cell locked with SingleUseLock bound to seal 3. Consume seal + owner to mint xUDT + UniqueType metadata cells - Add issueXudtWithSUS() convenience function for playground usage - Includes progress callback for tracking each transaction step - Handles TypeId calculation for UniqueType after inputs are finalized
- Update package selection table to show import statement instead of Web Component tag - Clarifies that @ckb-ccc/connector uses standard import pattern like other packages
✅ Deploy Preview for docsccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for liveccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
✅ Deploy Preview for appccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for apiccc ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Pull request overview
This PR replaces the previous single, monolithic CCC agent skill doc with a hub-and-spoke “multi-skill” layout under skills/, adds a /skill.md index route that lists skill dependencies and raw URLs, and introduces a new “AI Resources” docs section (EN + ZH) to help developers install, prompt, and verify their AI tooling against CCC docs.
Changes:
- Added a modular Agent Skills set (
ckb-ccc-fundamentalshub + spoke skills for signer setup, transactions, UDT, Spore, playground, and example-finding), plus maintenance guidance inskills/README.md. - Added an on-site skills index (
/skill.md) and updated docs verification +llms.txtto reference the new structure. - Added “AI Resources” documentation pages (setup, prompting, troubleshooting) in both English and Chinese, and updated docs navigation to include them.
Reviewed changes
Copilot reviewed 29 out of 29 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| skills/README.md | Maintenance guidance for updating skills and versioning. |
| skills/ckb-ccc-fundamentals/SKILL.md | Hub skill covering CKB/CCC fundamentals and doc/API-grounding workflow. |
| skills/ckb-ccc-signer-setup/SKILL.md | Spoke skill for wallet connection + signer creation patterns. |
| skills/ckb-ccc-transactions/SKILL.md | Spoke skill for CCC transaction composition pipeline and chain querying. |
| skills/ckb-ccc-udt/SKILL.md | Spoke skill for UDT/xUDT issuance/transfer patterns (SUS issuance example). |
| skills/ckb-ccc-spore/SKILL.md | Spoke skill for Spore/DOB creation/transfer/melt and DOB conventions. |
| skills/ckb-ccc-playground/SKILL.md | Spoke skill for CCC Playground usage, sharing, and contribution workflow. |
| skills/ckb-ccc-examples-finder/SKILL.md | Spoke skill for locating existing example code by category. |
| packages/examples/src/issueUdtSus.ts | New runnable example implementing xUDT SUS issuance flow with progress callback. |
| packages/docs/scripts/verify-llm.mjs | Updates verification checks to validate the new /skill.md route content. |
| packages/docs/public/skill.md | Removes the old monolithic skill document. |
| packages/docs/app/skill.md/route.ts | Adds /skill.md route that renders the skills index table + summaries. |
| packages/docs/app/llms.txt/route.ts | Updates llms notes and adds AI Resources to the index. |
| packages/docs/content/docs/meta.json | Adds AI Resources pages to the English docs navigation. |
| packages/docs/content/docs/meta.zh.json | Adds AI Resources pages to the Chinese docs navigation. |
| packages/docs/content/docs/getting-started/introduction.mdx | Adds AI Resources entry card on the intro page. |
| packages/docs/content/docs/getting-started/introduction.zh.mdx | Adds AI Resources entry card on the intro page (ZH). |
| packages/docs/content/docs/guides/playground.mdx | Updates example #2 to “Create a Spore” (doc snippet). |
| packages/docs/content/docs/guides/playground.zh.mdx | Updates example #2 to “Create a Spore” (doc snippet, ZH). |
| packages/docs/content/docs/ai-resources/index.mdx | New AI Resources section landing page (EN). |
| packages/docs/content/docs/ai-resources/index.zh.mdx | New AI Resources section landing page (ZH). |
| packages/docs/content/docs/ai-resources/set-up-ai-tools.mdx | New page: installing CCC skills into AI tools (EN). |
| packages/docs/content/docs/ai-resources/set-up-ai-tools.zh.mdx | New page: installing CCC skills into AI tools (ZH). |
| packages/docs/content/docs/ai-resources/prompting-best-practices.mdx | New page: prompt templates and grounding workflow (EN). |
| packages/docs/content/docs/ai-resources/prompting-best-practices.zh.mdx | New page: prompt templates and grounding workflow (ZH). |
| packages/docs/content/docs/ai-resources/verify-and-troubleshoot.mdx | New page: canary questions + troubleshooting flow (EN). |
| packages/docs/content/docs/ai-resources/verify-and-troubleshoot.zh.mdx | New page: canary questions + troubleshooting flow (ZH). |
| packages/docs/content/docs/ai-resources/meta.json | New section metadata for AI Resources (EN). |
| packages/docs/content/docs/ai-resources/meta.zh.json | New section metadata for AI Resources (ZH). |
- Add `--all` flag to npx skills add command in skill.md route for non-interactive installation - Add console.log to display Spore ID after creation in playground example (both EN and ZH) - Fix Chinese playground example description from "发行代币" to "创建 Spore" for accuracy
- Change `dependsOn` to `depends-on` in skills/README.md to match the actual YAML frontmatter field name used in SKILL.md files - Add descriptive comment to issueUdtSus.ts example
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
| @@ -0,0 +1,212 @@ | |||
| --- | |||
| name: ckb-ccc-spore | |||
| description: Covers creating, transferring, and melting Spore protocol NFTs/DOBs(on-chain digital objects) on CKB with CCC, including cluster handling and the DOB/0 and DOB/1 content-type conventions built on top of Spore (DNA-driven trait patterns, decoders, SVG composition). Use when the user asks about Spore, DOB, DOB/0, DOB/1, on-chain NFTs, or clusters on CKB — even if they just say "NFT" or "digital object" without naming Spore or DOB specifically. Builds on the standard transaction pattern in ckb-ccc-transactions. | |||
| 2. **规则是否在正确的作用域内?** 项目级规则仅适用于该项目。如果你从另一个仓库或项目外的临时文件进行测试,项目级规则不会生效——请改用全局/个人路径。 | ||
| 3. **工具是否真的将规则附加到了当前会话?** 对于没有基于文件的规则机制的纯聊天工具(如普通 ChatGPT 等),你需要为每次会话粘贴系统提示片段,而非只粘贴一次——详见[配置 AI 工具](./set-up-ai-tools)。 | ||
| 4. **上下文窗口是否已满?** 在长时间的会话中,早期加载的规则可能被挤出或降低优先级。开启一个新会话,重新问一个金丝雀问题,再下结论说配置有问题。 | ||
| 5. **助手是否拉取了一份过期的副本?** 已安装的 skill 文件是某个时间点的副本,并非实时拉取。运行 `npx skills update` 来更新——参见[保持 skill 最新](./set-up-ai-tools#keep-skills-up-to-date)。 |
There was a problem hiding this comment.
Actionable comments posted: 13
🧹 Nitpick comments (1)
skills/ckb-ccc-spore/SKILL.md (1)
42-44: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winAvoid
Math.random()for minting DNA.If DNA controls visible traits or rarity,
Math.random()is predictable. Use a cryptographically secure RNG appropriate to the target runtime, and document that this helper is demo-only if predictability is intentional.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@skills/ckb-ccc-spore/SKILL.md` around lines 42 - 44, Update generateSimpleDNA to use a cryptographically secure random number generator supported by the target runtime instead of Math.random(), while preserving the requested hexadecimal DNA length. If this helper is intentionally demo-only and predictable output is acceptable, document that limitation directly with the helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/docs/content/docs/ai-resources/index.mdx`:
- Around line 15-34: Fix sibling-page links in
packages/docs/content/docs/ai-resources/index.mdx (lines 15-34) by removing the
redundant ai-resources/ prefix from all three list links, the Callout link, and
all three Card hrefs. Apply the same link corrections to the equivalent links in
packages/docs/content/docs/ai-resources/index.zh.mdx (lines 15-34), using bare
./xxx paths.
- Around line 15-21: Update all relative links in the ai-resources index page,
including the three list items, the Callout link, and the three Card hrefs, to
remove the redundant ai-resources/ path segment and use ./set-up-ai-tools,
./verify-and-troubleshoot, and ./prompting-best-practices.
In `@packages/docs/content/docs/ai-resources/index.zh.mdx`:
- Around line 15-21: Update the links in the Chinese AI resources index,
including the corresponding Callout link, to remove the duplicated
`ai-resources/` path segment. Preserve each link’s target page and use paths
relative to the index file’s location.
In `@packages/examples/src/issueUdtSus.ts`:
- Around line 268-275: Move the Playground invocation of issueXudtWithSUS and
its result logging out of module-level execution into a separately called
function or documentation-only snippet. Ensure importing the module does not
initiate signing or broadcasting, while preserving the existing invocation
behavior when explicitly called.
- Around line 70-75: Validate all mint inputs before any broadcast: update the
parameter validation near the issueUdtSus flow to require integer decimals in
0..255, precompute metadata, and validate supply as a non-negative uint128
before createSealCell or Step 1. Apply the same integer-decimal validation and
preflight metadata/supply checks in packages/examples/src/issueUdtSus.ts lines
70-75 and 125-147, and mirror both changes in skills/ckb-ccc-udt/SKILL.md lines
91-96 and 146-168.
- Around line 32-34: Make totalSupply use one explicit unit convention across
IssueXudtSusParams and its serialization path at issueUdtSus, either narrowing
the accepted representation or documenting bigint as already scaled while
preserving consistent ccc.fixedPointFrom behavior. Update
packages/examples/src/issueUdtSus.ts lines 32-34 and 208, and align
skills/ckb-ccc-udt/SKILL.md lines 53-55 and 360-362 so the checklist and
documentation state the same contract.
In `@skills/ckb-ccc-fundamentals/SKILL.md`:
- Line 177: Tag every affected fenced documentation block to satisfy
markdownlint MD040: use http for request examples at
skills/ckb-ccc-fundamentals/SKILL.md lines 177, 187, and 199 and
skills/ckb-ccc-examples-finder/SKILL.md lines 22-24; use text for URL-only
examples at skills/ckb-ccc-fundamentals/SKILL.md lines 221 and 227.
In `@skills/ckb-ccc-playground/SKILL.md`:
- Around line 94-97: Update the `?src=` documentation to explicitly warn that
fetched raw URLs contain untrusted executable code and run with the Playground’s
pre-connected signer. Recommend inspecting the source and pinning it to an
immutable Git commit before selecting Run, particularly when using mainnet,
while preserving the existing link-longevity guidance.
In `@skills/ckb-ccc-signer-setup/SKILL.md`:
- Line 68: Update the Verify step in SKILL.md to use an actual confirmation
wait, replacing the single getTransaction(txHash) polling description with await
client.waitTransaction(txHash, 1), or document an explicit retry loop that
checks confirmation status.
- Around line 63-76: Update the signer setup example around CKB_PRIVATE_KEY to
explicitly validate that process.env.CKB_PRIVATE_KEY is set before constructing
SignerCkbPrivateKey. Fail immediately with a clear error when it is missing,
then pass the validated value to the constructor instead of relying on the
non-null assertion.
In `@skills/ckb-ccc-spore/SKILL.md`:
- Around line 165-183: Make the Spore transfer example self-contained by adding
the required ccc import and showing initialization or definition of signer and
recipientAddr before they are used. Keep the existing createSpore and
transferSpore flow intact, and ensure ccc.Address.fromString receives the
initialized signer.client.
- Around line 60-68: Update both cluster-creation examples to capture the
transaction hash returned by signer.sendTransaction and await
signer.client.waitTransaction before invoking ccc.spore.createSpore. Preserve
the existing fee completion and minting flow, ensuring cluster indexing
completes before createSpore resolves the cluster via assertCluster.
In `@skills/ckb-ccc-transactions/SKILL.md`:
- Around line 70-72: The capacity guidance in the SKILL.md gotcha row and
checklist must describe output-dependent occupied capacity rather than a fixed
61 CKB minimum. Update both references to state that occupied capacity is
calculated from each output’s lock, type script, and data, while retaining the
instruction to use CCC helpers instead of manual calculation.
---
Nitpick comments:
In `@skills/ckb-ccc-spore/SKILL.md`:
- Around line 42-44: Update generateSimpleDNA to use a cryptographically secure
random number generator supported by the target runtime instead of
Math.random(), while preserving the requested hexadecimal DNA length. If this
helper is intentionally demo-only and predictable output is acceptable, document
that limitation directly with the helper.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5085d320-2f18-4c6c-85dc-a24f02563818
📒 Files selected for processing (29)
packages/docs/app/llms.txt/route.tspackages/docs/app/skill.md/route.tspackages/docs/content/docs/ai-resources/index.mdxpackages/docs/content/docs/ai-resources/index.zh.mdxpackages/docs/content/docs/ai-resources/meta.jsonpackages/docs/content/docs/ai-resources/meta.zh.jsonpackages/docs/content/docs/ai-resources/prompting-best-practices.mdxpackages/docs/content/docs/ai-resources/prompting-best-practices.zh.mdxpackages/docs/content/docs/ai-resources/set-up-ai-tools.mdxpackages/docs/content/docs/ai-resources/set-up-ai-tools.zh.mdxpackages/docs/content/docs/ai-resources/verify-and-troubleshoot.mdxpackages/docs/content/docs/ai-resources/verify-and-troubleshoot.zh.mdxpackages/docs/content/docs/getting-started/introduction.mdxpackages/docs/content/docs/getting-started/introduction.zh.mdxpackages/docs/content/docs/guides/playground.mdxpackages/docs/content/docs/guides/playground.zh.mdxpackages/docs/content/docs/meta.jsonpackages/docs/content/docs/meta.zh.jsonpackages/docs/public/skill.mdpackages/docs/scripts/verify-llm.mjspackages/examples/src/issueUdtSus.tsskills/README.mdskills/ckb-ccc-examples-finder/SKILL.mdskills/ckb-ccc-fundamentals/SKILL.mdskills/ckb-ccc-playground/SKILL.mdskills/ckb-ccc-signer-setup/SKILL.mdskills/ckb-ccc-spore/SKILL.mdskills/ckb-ccc-transactions/SKILL.mdskills/ckb-ccc-udt/SKILL.md
💤 Files with no reviewable changes (1)
- packages/docs/public/skill.md
| 1. **[Set up your tool](./ai-resources/set-up-ai-tools)** — one-time config so your assistant always loads CCC's rules (under 2 minutes). | ||
| 2. **[Verify it worked](./ai-resources/verify-and-troubleshoot)** — ask one canary question to confirm the rules actually loaded. Don't skip this: a silently-failed setup looks configured but isn't. | ||
| 3. **[Prompt it well](./ai-resources/prompting-best-practices)** — per request, name the exact package and point it at the relevant guide. | ||
|
|
||
| <Callout type="info"> | ||
| New here? Start with **[Set Up Your AI Tools](./ai-resources/set-up-ai-tools)** and do the 2-minute setup for the tool you use — everything else builds on it. | ||
| </Callout> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Relative links double the ai-resources/ path segment.
This file lives at ai-resources/index.mdx, so relative links should be ./set-up-ai-tools, ./verify-and-troubleshoot, ./prompting-best-practices — matching the pattern used consistently in the sibling pages (prompting-best-practices.mdx, set-up-ai-tools.mdx, verify-and-troubleshoot.mdx, all of which link to each other with bare ./xxx, no ai-resources/ prefix). Every link here (list items, the Callout, and all three Card hrefs) instead uses ./ai-resources/xxx, which resolves to a nonexistent ai-resources/ai-resources/xxx path and 404s.
🔗 Proposed fix
-1. **[Set up your tool](./ai-resources/set-up-ai-tools)** — one-time config so your assistant always loads CCC's rules (under 2 minutes).
-2. **[Verify it worked](./ai-resources/verify-and-troubleshoot)** — ask one canary question to confirm the rules actually loaded. Don't skip this: a silently-failed setup looks configured but isn't.
-3. **[Prompt it well](./ai-resources/prompting-best-practices)** — per request, name the exact package and point it at the relevant guide.
+1. **[Set up your tool](./set-up-ai-tools)** — one-time config so your assistant always loads CCC's rules (under 2 minutes).
+2. **[Verify it worked](./verify-and-troubleshoot)** — ask one canary question to confirm the rules actually loaded. Don't skip this: a silently-failed setup looks configured but isn't.
+3. **[Prompt it well](./prompting-best-practices)** — per request, name the exact package and point it at the relevant guide.
<Callout type="info">
- New here? Start with **[Set Up Your AI Tools](./ai-resources/set-up-ai-tools)** and do the 2-minute setup for the tool you use — everything else builds on it.
+ New here? Start with **[Set Up Your AI Tools](./set-up-ai-tools)** and do the 2-minute setup for the tool you use — everything else builds on it.
</Callout>
...
- <Card title="Set Up Your AI Tools" icon={<Wrench />} href="./ai-resources/set-up-ai-tools">
+ <Card title="Set Up Your AI Tools" icon={<Wrench />} href="./set-up-ai-tools">
...
- <Card title="Prompting Best Practices" icon={<MessageSquare />} href="./ai-resources/prompting-best-practices">
+ <Card title="Prompting Best Practices" icon={<MessageSquare />} href="./prompting-best-practices">
...
- <Card title="Verify & Troubleshoot" icon={<ShieldCheck />} href="./ai-resources/verify-and-troubleshoot">
+ <Card title="Verify & Troubleshoot" icon={<ShieldCheck />} href="./verify-and-troubleshoot">Also applies to: 26-26, 30-30, 34-34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/docs/content/docs/ai-resources/index.mdx` around lines 15 - 21,
Update all relative links in the ai-resources index page, including the three
list items, the Callout link, and the three Card hrefs, to remove the redundant
ai-resources/ path segment and use ./set-up-ai-tools, ./verify-and-troubleshoot,
and ./prompting-best-practices.
| 1. **[Set up your tool](./ai-resources/set-up-ai-tools)** — one-time config so your assistant always loads CCC's rules (under 2 minutes). | ||
| 2. **[Verify it worked](./ai-resources/verify-and-troubleshoot)** — ask one canary question to confirm the rules actually loaded. Don't skip this: a silently-failed setup looks configured but isn't. | ||
| 3. **[Prompt it well](./ai-resources/prompting-best-practices)** — per request, name the exact package and point it at the relevant guide. | ||
|
|
||
| <Callout type="info"> | ||
| New here? Start with **[Set Up Your AI Tools](./ai-resources/set-up-ai-tools)** and do the 2-minute setup for the tool you use — everything else builds on it. | ||
| </Callout> | ||
|
|
||
| ## Pages in this section | ||
|
|
||
| <Cards cols={2}> | ||
| <Card title="Set Up Your AI Tools" icon={<Wrench />} href="./ai-resources/set-up-ai-tools"> | ||
| Copy-paste config for Cursor, Claude Code, GitHub Copilot, Windsurf, and ChatGPT — plus which CCC links to point your assistant at. | ||
| </Card> | ||
|
|
||
| <Card title="Prompting Best Practices" icon={<MessageSquare />} href="./ai-resources/prompting-best-practices"> | ||
| A before/after example, prompt templates by task, and the specific CKB mistakes AI makes — with the one-line correction for each. | ||
| </Card> | ||
|
|
||
| <Card title="Verify & Troubleshoot" icon={<ShieldCheck />} href="./ai-resources/verify-and-troubleshoot"> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Broken landing-page links in both index.mdx and index.zh.mdx. Both files self-reference from ai-resources/index(.zh).mdx using ./ai-resources/set-up-ai-tools, ./ai-resources/verify-and-troubleshoot, ./ai-resources/prompting-best-practices, which doubles the ai-resources/ segment and 404s — every other page in this directory (prompting-best-practices.mdx, set-up-ai-tools.mdx, verify-and-troubleshoot.mdx) correctly links to siblings with the bare ./xxx form.
packages/docs/content/docs/ai-resources/index.mdx#L15-L34: strip theai-resources/prefix from all three list-item links, theCalloutlink, and all threeCardhrefs.packages/docs/content/docs/ai-resources/index.zh.mdx#L15-L34: apply the same fix to the Chinese translation's equivalent links.
📍 Affects 2 files
packages/docs/content/docs/ai-resources/index.mdx#L15-L34(this comment)packages/docs/content/docs/ai-resources/index.zh.mdx#L15-L34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/docs/content/docs/ai-resources/index.mdx` around lines 15 - 34, Fix
sibling-page links in packages/docs/content/docs/ai-resources/index.mdx (lines
15-34) by removing the redundant ai-resources/ prefix from all three list links,
the Callout link, and all three Card hrefs. Apply the same link corrections to
the equivalent links in packages/docs/content/docs/ai-resources/index.zh.mdx
(lines 15-34), using bare ./xxx paths.
| 1. **[配置你的工具](./ai-resources/set-up-ai-tools)**——一次性配置,让你的助手始终加载 CCC 的规则(不到 2 分钟)。 | ||
| 2. **[验证配置是否生效](./ai-resources/verify-and-troubleshoot)**——用一个金丝雀问题确认规则确实被加载了。不要跳过这一步:静默加载失败的配置看起来配好了,但实际上没有。 | ||
| 3. **[写好提示词](./ai-resources/prompting-best-practices)**——每次请求时,明确指出要用的包名,并将其引导至相关的指南页面。 | ||
|
|
||
| <Callout type="info"> | ||
| 新手?从 **[配置你的工具](./ai-resources/set-up-ai-tools)** 开始,花 2 分钟为你使用的工具完成配置——其余内容都建立在这个基础上。 | ||
| </Callout> |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Same broken-link pattern as the English version.
Identical issue to index.mdx: every link (./ai-resources/set-up-ai-tools, ./ai-resources/verify-and-troubleshoot, ./ai-resources/prompting-best-practices) doubles the ai-resources/ segment relative to this file's own location, breaking navigation. See the consolidated comment for the shared fix.
Also applies to: 26-26, 30-30, 34-34
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/docs/content/docs/ai-resources/index.zh.mdx` around lines 15 - 21,
Update the links in the Chinese AI resources index, including the corresponding
Callout link, to remove the duplicated `ai-resources/` path segment. Preserve
each link’s target page and use paths relative to the index file’s location.
| interface IssueXudtSusParams extends TokenMetadata { | ||
| /** Human-readable total supply, e.g. 100_000_000 (converted to Shannon internally) */ | ||
| totalSupply: ccc.FixedPointLike; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
fd -t f -e ts . packages/core |
xargs rg -n -C 8 'function fixedPointFrom|function numBeToBytes'Repository: ckb-devrel/ccc
Length of output: 2623
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== issueUdtSus.ts ==\n'
sed -n '1,260p' packages/examples/src/issueUdtSus.ts | cat -n
printf '\n== fixedPoint/index.ts ==\n'
sed -n '1,140p' packages/core/src/fixedPoint/index.ts | cat -n
printf '\n== skill doc excerpts ==\n'
sed -n '45,70p' skills/ckb-ccc-udt/SKILL.md | cat -n
printf '\n---\n'
sed -n '350,370p' skills/ckb-ccc-udt/SKILL.md | cat -nRepository: ckb-devrel/ccc
Length of output: 15609
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from pathlib import Path
p = Path('packages/examples/src/issueUdtSus.ts')
text = p.read_text()
for needle in [
'totalSupply:',
'fixedPointFrom(totalSupply, decimals)',
'numLeToBytes(',
]:
print(f"\n== {needle} ==")
for i, line in enumerate(text.splitlines(), 1):
if needle in line:
start=max(1, i-3); end=min(len(text.splitlines()), i+3)
for j in range(start, end+1):
print(f"{j:4}: {text.splitlines()[j-1]}")
break
PYRepository: ckb-devrel/ccc
Length of output: 1124
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '\n== FixedPointLike definition and fixedPointFrom usage ==\n'
rg -n -C 3 'type FixedPointLike|interface FixedPointLike|export type FixedPointLike|fixedPointFrom\(' packages/core packages/examples skills
printf '\n== issueUdtSus relevant excerpt ==\n'
sed -n '24,220p' packages/examples/src/issueUdtSus.ts | cat -nRepository: ckb-devrel/ccc
Length of output: 47718
Make totalSupply’s units explicit.
ccc.fixedPointFrom leaves bigint unchanged but scales number/string inputs, so this API accepts both human-readable amounts and raw on-chain integers under the same type. Narrow totalSupply to one representation or document bigint as already-scaled, and align the skill doc with the same contract.
packages/examples/src/issueUdtSus.ts#L32-L34/#L208-L208: keep the parameter type and serialization path on one unit rule.skills/ckb-ccc-udt/SKILL.md#L53-L55/#L360-L362: remove the checklist/docs contradiction.
📍 Affects 2 files
packages/examples/src/issueUdtSus.ts#L32-L34(this comment)packages/examples/src/issueUdtSus.ts#L208-L208skills/ckb-ccc-udt/SKILL.md#L53-L55skills/ckb-ccc-udt/SKILL.md#L360-L362
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/examples/src/issueUdtSus.ts` around lines 32 - 34, Make totalSupply
use one explicit unit convention across IssueXudtSusParams and its serialization
path at issueUdtSus, either narrowing the accepted representation or documenting
bigint as already scaled while preserving consistent ccc.fixedPointFrom
behavior. Update packages/examples/src/issueUdtSus.ts lines 32-34 and 208, and
align skills/ckb-ccc-udt/SKILL.md lines 53-55 and 360-362 so the checklist and
documentation state the same contract.
| if (!symbol) { | ||
| throw new Error("symbol is required"); | ||
| } | ||
| if (decimals < 0 || decimals > 255) { | ||
| throw new Error("decimals must be within 0-255 (1-byte field)"); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Validate all mint parameters before broadcasting the seal.
Invalid decimals, metadata, or an unencodable supply currently fail only after the seal and possibly owner transaction are sent, leaving a partial SUS flow. Precompute and validate metadata plus a non-negative uint128 supply before Step 1.
packages/examples/src/issueUdtSus.ts#L70-L75: require an integer decimal value in0..255.packages/examples/src/issueUdtSus.ts#L125-L147: preflight metadata and supply bounds beforecreateSealCell.skills/ckb-ccc-udt/SKILL.md#L91-L96: mirror the integer validation in the documented code.skills/ckb-ccc-udt/SKILL.md#L146-L168: mirror the preflight step before any broadcast.
📍 Affects 2 files
packages/examples/src/issueUdtSus.ts#L70-L75(this comment)packages/examples/src/issueUdtSus.ts#L125-L147skills/ckb-ccc-udt/SKILL.md#L91-L96skills/ckb-ccc-udt/SKILL.md#L146-L168
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/examples/src/issueUdtSus.ts` around lines 70 - 75, Validate all mint
inputs before any broadcast: update the parameter validation near the
issueUdtSus flow to require integer decimals in 0..255, precompute metadata, and
validate supply as a non-negative uint128 before createSealCell or Step 1. Apply
the same integer-decimal validation and preflight metadata/supply checks in
packages/examples/src/issueUdtSus.ts lines 70-75 and 125-147, and mirror both
changes in skills/ckb-ccc-udt/SKILL.md lines 91-96 and 146-168.
| 1. **Import and connect** — Install `@ckb-ccc/shell`. Create client: `new ccc.ClientPublicTestnet()` or `ClientPublicMainnet()`. | ||
| 2. **Create signer** — `new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!)`. Never hardcode keys. | ||
| 3. **Check connection** — Some signers require `await signer.connect()`. Check with `await signer.isConnected()` if operations fail unexpectedly. | ||
| 4. **Query data** — `await signer.getRecommendedAddress()`, `await signer.getBalance()`, `for await (const cell of client.findCellsByLock(...))`. | ||
| 5. **Build and send** — Follow the transaction-composition pattern in `ckb-ccc-transactions`; the pattern is identical regardless of how the signer was created. | ||
| 6. **Verify** — Log `txHash`; use `client.getTransaction(txHash)` to poll for confirmation. | ||
|
|
||
| ```typescript | ||
| import { ccc } from "@ckb-ccc/shell"; | ||
|
|
||
| // Always load private key from environment — never hardcode | ||
| const client = new ccc.ClientPublicTestnet(); // or ClientPublicMainnet | ||
| const signer = new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!); | ||
| await signer.connect(); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
Fail fast when CKB_PRIVATE_KEY is missing.
The ! only suppresses TypeScript checking; an unset environment variable still reaches the constructor as undefined. Since this is a copyable backend example, validate the variable explicitly.
Suggested fix
const client = new ccc.ClientPublicTestnet(); // or ClientPublicMainnet
-const signer = new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!);
+const privateKey = process.env.CKB_PRIVATE_KEY;
+if (!privateKey) throw new Error("CKB_PRIVATE_KEY is required");
+const signer = new ccc.SignerCkbPrivateKey(client, privateKey);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| 1. **Import and connect** — Install `@ckb-ccc/shell`. Create client: `new ccc.ClientPublicTestnet()` or `ClientPublicMainnet()`. | |
| 2. **Create signer** — `new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!)`. Never hardcode keys. | |
| 3. **Check connection** — Some signers require `await signer.connect()`. Check with `await signer.isConnected()` if operations fail unexpectedly. | |
| 4. **Query data** — `await signer.getRecommendedAddress()`, `await signer.getBalance()`, `for await (const cell of client.findCellsByLock(...))`. | |
| 5. **Build and send** — Follow the transaction-composition pattern in `ckb-ccc-transactions`; the pattern is identical regardless of how the signer was created. | |
| 6. **Verify** — Log `txHash`; use `client.getTransaction(txHash)` to poll for confirmation. | |
| ```typescript | |
| import { ccc } from "@ckb-ccc/shell"; | |
| // Always load private key from environment — never hardcode | |
| const client = new ccc.ClientPublicTestnet(); // or ClientPublicMainnet | |
| const signer = new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!); | |
| await signer.connect(); | |
| 1. **Import and connect** — Install `@ckb-ccc/shell`. Create client: `new ccc.ClientPublicTestnet()` or `ClientPublicMainnet()`. | |
| 2. **Create signer** — `new ccc.SignerCkbPrivateKey(client, process.env.CKB_PRIVATE_KEY!)`. Never hardcode keys. | |
| 3. **Check connection** — Some signers require `await signer.connect()`. Check with `await signer.isConnected()` if operations fail unexpectedly. | |
| 4. **Query data** — `await signer.getRecommendedAddress()`, `await signer.getBalance()`, `for await (const cell of client.findCellsByLock(...))`. | |
| 5. **Build and send** — Follow the transaction-composition pattern in `ckb-ccc-transactions`; the pattern is identical regardless of how the signer was created. | |
| 6. **Verify** — Log `txHash`; use `client.getTransaction(txHash)` to poll for confirmation. | |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/ckb-ccc-signer-setup/SKILL.md` around lines 63 - 76, Update the signer
setup example around CKB_PRIVATE_KEY to explicitly validate that
process.env.CKB_PRIVATE_KEY is set before constructing SignerCkbPrivateKey. Fail
immediately with a clear error when it is missing, then pass the validated value
to the constructor instead of relying on the non-null assertion.
| 3. **Check connection** — Some signers require `await signer.connect()`. Check with `await signer.isConnected()` if operations fail unexpectedly. | ||
| 4. **Query data** — `await signer.getRecommendedAddress()`, `await signer.getBalance()`, `for await (const cell of client.findCellsByLock(...))`. | ||
| 5. **Build and send** — Follow the transaction-composition pattern in `ckb-ccc-transactions`; the pattern is identical regardless of how the signer was created. | ||
| 6. **Verify** — Log `txHash`; use `client.getTransaction(txHash)` to poll for confirmation. |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Use an actual confirmation wait instead of describing getTransaction() as polling.
A single client.getTransaction(txHash) call does not poll or guarantee confirmation. Point readers to await client.waitTransaction(txHash, 1) or show an explicit retry loop with confirmation checks.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/ckb-ccc-signer-setup/SKILL.md` at line 68, Update the Verify step in
SKILL.md to use an actual confirmation wait, replacing the single
getTransaction(txHash) polling description with await
client.waitTransaction(txHash, 1), or document an explicit retry loop that
checks confirmation status.
| ```typescript | ||
| import { spore } from "@ckb-ccc/spore"; // or ccc.spore from @ckb-ccc/shell | ||
|
|
||
| // Create a Spore (stores content permanently on-chain) | ||
| const { tx, id: sporeId } = await spore.createSpore({ | ||
| signer, | ||
| data: { | ||
| contentType: "text/plain", | ||
| content: new TextEncoder().encode("Hello, Spore!"), | ||
| }, | ||
| }); | ||
| await tx.completeInputsByCapacity(signer); | ||
| await tx.completeFeeBy(signer); | ||
| const txHash = await signer.sendTransaction(tx); | ||
| // Save sporeId — it's the Type script args, needed for transfer/melt | ||
|
|
||
| // Transfer a Spore | ||
| const { script: newOwner } = await ccc.Address.fromString(recipientAddr, signer.client); | ||
| const { tx: transferTx } = await spore.transferSpore({ signer, id: sporeId, to: newOwner }); |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Make the transfer example self-contained.
The block imports only spore but references undefined ccc, signer, and recipientAddr; pasting it as shown fails before the transfer runs.
Suggested fix
+import { ccc } from "`@ckb-ccc/ccc`";
+import { signer } from "`@ckb-ccc/playground`"; // replace with an application signer outside Playground
import { spore } from "`@ckb-ccc/spore`";
+const recipientAddr = await signer.getRecommendedAddress(); // replace with the intended recipient📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ```typescript | |
| import { spore } from "@ckb-ccc/spore"; // or ccc.spore from @ckb-ccc/shell | |
| // Create a Spore (stores content permanently on-chain) | |
| const { tx, id: sporeId } = await spore.createSpore({ | |
| signer, | |
| data: { | |
| contentType: "text/plain", | |
| content: new TextEncoder().encode("Hello, Spore!"), | |
| }, | |
| }); | |
| await tx.completeInputsByCapacity(signer); | |
| await tx.completeFeeBy(signer); | |
| const txHash = await signer.sendTransaction(tx); | |
| // Save sporeId — it's the Type script args, needed for transfer/melt | |
| // Transfer a Spore | |
| const { script: newOwner } = await ccc.Address.fromString(recipientAddr, signer.client); | |
| const { tx: transferTx } = await spore.transferSpore({ signer, id: sporeId, to: newOwner }); | |
| import { ccc } from "`@ckb-ccc/ccc`"; | |
| import { signer } from "`@ckb-ccc/playground`"; // replace with an application signer outside Playground | |
| import { spore } from "`@ckb-ccc/spore`"; // or ccc.spore from `@ckb-ccc/shell` | |
| const recipientAddr = await signer.getRecommendedAddress(); // replace with the intended recipient | |
| // Create a Spore (stores content permanently on-chain) | |
| const { tx, id: sporeId } = await spore.createSpore({ | |
| signer, | |
| data: { | |
| contentType: "text/plain", | |
| content: new TextEncoder().encode("Hello, Spore!"), | |
| }, | |
| }); | |
| await tx.completeInputsByCapacity(signer); | |
| await tx.completeFeeBy(signer); | |
| const txHash = await signer.sendTransaction(tx); | |
| // Save sporeId — it's the Type script args, needed for transfer/melt | |
| // Transfer a Spore | |
| const { script: newOwner } = await ccc.Address.fromString(recipientAddr, signer.client); | |
| const { tx: transferTx } = await spore.transferSpore({ signer, id: sporeId, to: newOwner }); |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/ckb-ccc-spore/SKILL.md` around lines 165 - 183, Make the Spore
transfer example self-contained by adding the required ccc import and showing
initialization or definition of signer and recipientAddr before they are used.
Keep the existing createSpore and transferSpore flow intact, and ensure
ccc.Address.fromString receives the initialized signer.client.
| | `"not enough capacity"` | Insufficient CKB | Fund the address; each output cell needs ≥ 61 CKB | | ||
| | `"InsufficientCellCapacity"` | Output cell below minimum | Each basic output needs ≥ 61 CKB capacity; use CCC helpers, not manual calculation | | ||
| | Transaction rejected by node | Fee too low or missing | Always call `completeFeeBy` after `completeInputsByCapacity`; omit fee rate arg for automatic rate | |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== File outline =="
ast-grep outline skills/ckb-ccc-transactions/SKILL.md --view expanded || true
echo
echo "== Relevant lines =="
sed -n '1,140p' skills/ckb-ccc-transactions/SKILL.md | cat -nRepository: ckb-devrel/ccc
Length of output: 5322
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Search for the minimum capacity guidance elsewhere in the repo.
rg -n '61 CKB|InsufficientCellCapacity|occupied capacity|completeFeeBy|completeInputsByCapacity' skills -SRepository: ckb-devrel/ccc
Length of output: 5181
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read only the relevant section if it exists.
if [ -f skills/ckb-ccc-transactions/SKILL.md ]; then
sed -n '60,100p' skills/ckb-ccc-transactions/SKILL.md | cat -n
fi
# Find whether the doc itself distinguishes simple outputs from custom outputs.
rg -n 'standard empty-data baseline|custom locks|custom types|occupied capacity|minimum capacity|61 CKB' skills/ckb-ccc-transactions/SKILL.md -SRepository: ckb-devrel/ccc
Length of output: 2381
🌐 Web query:
CKB occupied capacity minimum output depends on lock type script and data 61 CKB baseline documentation
💡 Result:
In Nervos CKB, the capacity of a cell functions as both its balance of CKB tokens and its storage limit [1][2][3]. When creating a transaction output, the cell's capacity must be greater than or equal to its occupied capacity, which is the sum of the bytes required to store all its fields: capacity, data, lock, and type [1][4][5]. The formula for calculating the minimum occupied capacity (in bytes) is [4][5][6]: Occupied Capacity = 8 + len(data) + occupied(lock) + occupied(type) Where: - 8 bytes: Required for the capacity field itself [4][5][6]. - len(data): The size of the data stored in the cell [4][5][6]. - occupied(lock): The size of the lock script, calculated as: 32 (code_hash) + 1 (hash_type) + len(args) [4][5][6]. - occupied(type): If present, calculated as: 32 (code_hash) + 1 (hash_type) + len(args). If absent, this is 0 [4][5]. The "61 CKB" baseline often cited refers to the minimum capacity required for a standard cell using the default SECP256K1-BLAKE160 lock script with empty data and no type script [1][4][6]. Specifically: 8 (capacity) + 32 (code_hash) + 1 (hash_type) + 20 (args) = 61 bytes [1][6]. Since each byte of storage requires 1 CKByte of capacity, such a cell must hold at least 61 CKBytes [1][6]. It is standard practice to allocate 62 or more CKBytes to accommodate transaction fees [1][3].
Citations:
- 1: https://docs.nervos.org/docs/tech-explanation/capacity
- 2: https://nervosnetwork.github.io/rfcs/rfcs/0022-transaction-structure/0022-transaction-structure.html
- 3: https://docs.nervos.org/docs/getting-started/how-ckb-works
- 4: https://github.com/nervosnetwork/ckb/wiki/Occupied-Capacity
- 5: Spec about how to compute cell occupied capacity nervosnetwork/rfcs#118
- 6: https://pocket-node-learn-ckb.vercel.app/lessons/03-capacity-calculator
Describe capacity as output-dependent.
61 CKB is only the baseline for a simple standard output; occupied capacity varies with the lock, type script, and data. Update the gotcha row and checklist item so they refer to calculated occupied capacity instead of a fixed minimum.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@skills/ckb-ccc-transactions/SKILL.md` around lines 70 - 72, The capacity
guidance in the SKILL.md gotcha row and checklist must describe output-dependent
occupied capacity rather than a fixed 61 CKB minimum. Update both references to
state that occupied capacity is calculated from each output’s lock, type script,
and data, while retaining the instruction to use CCC helpers instead of manual
calculation.

This PR introduces a modular multi-skill architecture for CCC's AI coding assistant support, replacing the previous monolithic
skill.mdwith a hub-and-spoke structure. It also adds comprehensive AI Resources documentation to help developers configure and use their AI tools effectively with CCC.Changes
Multi-Skill Architecture
AI Resources Documentation
Added a new documentation section with 4 pages (English and Chinese):
npx skills add ckb-devrel/ccc, keep-skills-up-to-date workflowNote: The current prompt templates include detailed constraints to ensure accuracy. We will be conducting deep testing to find the optimal balance between prompt conciseness and output accuracy, and will iterate on these templates based on real-world usage.
npx skills check/updateDocumentation Infrastructure
packages/docs/public/skill.md/skill.mdroute serving a Markdown table with skill dependencies and installation instructionsllms.txtroute to reference the new skill structureExamples
XudtSusIssuerclass for xUDT Single-Use-Seal pattern issuance